package model.action.basic_function_action;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import model.dap.dao.ConsumerDAO;
import model.dap.domain.Consumer;
import model.dap.mapper.ConsumerMapper;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.ModelDriven;
//import com.sun.mail.smtp.SMTPAddressFailedException;

import common.base.BaseAction;
import common.util.EmailValidator;
import common.util.ValidateUtil;

import java.io.IOException;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletContext;

import model.dap.dao.MailConfigDAO;
import model.dap.domain.MailConfig;
import model.dap.mapper.MailConfigMapper;

//import javax.mail.SendFailedException;

@Results({
		@Result(name = "error", type = "tiles", location = "tiles.ConsumerRegister"),
		@Result(name = "successex", type = "redirectAction", location = "Register_Consumer.html"),
		@Result(name = "success", type = "redirectAction", location = "home.html"),
})
@ParentPackage("master_tiles")
public class RegisterConsumerAction extends BaseAction implements
		ModelDriven<Consumer> {
	protected static Logger log = Logger
			.getLogger(RegisterConsumerAction.class);
	private static final long serialVersionUID = 1L;
	private Consumer consumer = new Consumer();
	private String birthDay;
	private static int errTimes=0;
	private String to, genderSelected;
	private static EmailValidator emV = new EmailValidator();
	
	public String getGenderSelected() {
		return genderSelected;
	}
	public void setGenderSelected(String genderSelected) {
		this.genderSelected = genderSelected;
	}

	private int typeID;

	// ======================================================================================================
	public String getBirthDay() {
		return birthDay;
	}
	public static int getErrTimes() {
		return errTimes;
	}

	public void setBirthDay(String birthDay) {
		this.birthDay = birthDay;
	}
	public static void setErrTimes(int errTimes) {
		RegisterConsumerAction.errTimes = errTimes;
	}
	
	public String getTo() {
		return to;
	}

	public void setTo(String to) {
		this.to = to;
	}

	public int getTypeID() {
		return typeID;
	}

	public void setTypeID(int typeID) {
		this.typeID = typeID;
	}

	public Consumer getUers() {
		return consumer;
	}

	public void setUser(Consumer consumer) {
		this.consumer = consumer;
	}

// --- Bien cua mail------
	private static MailConfig mailConfig = new MailConfig();
	
	static Properties properties = new Properties();
	
	public Consumer getConsumer() {
		return consumer;
	}

	public void setConsumer(Consumer consumer) {
		this.consumer = consumer;
	}

	public static MailConfig getMailConfig() {
		return mailConfig;
	}

	public static void setMailConfig(MailConfig mailConfig) {
		RegisterConsumerAction.mailConfig = mailConfig;
	}

	public static Properties getProperties() {
		return properties;
	}

	public static void setProperties(Properties properties) {
		RegisterConsumerAction.properties = properties;
	}
	// ======================================================================================================
	// REGISTER CONSUMER
	private String password, confirmPassword;
	
	// Image
	// Save images
	private File myfile;
	private String myfileFileName, myfileContentType;
	private String avatarUrl1;
	
	public File getMyfile() {
		return myfile;
	}
	public void setMyfile(File myfile) {
		this.myfile = myfile;
	}
	
	public String getMyfileFileName() {
		return myfileFileName;
	}
	public void setMyfileFileName(String myfileFileName) {
		this.myfileFileName = myfileFileName;
	}
	public String getMyfileContentType() {
		return myfileContentType;
	}
	public void setMyfileContentType(String myfileContentType) {
		this.myfileContentType = myfileContentType;
	}

	

	public String getAvatarUrl1() {
		return avatarUrl1;
	}
	public void setAvatarUrl1(String avatarUrl1) {
		this.avatarUrl1 = avatarUrl1;
	}
	@Action("/master/insert-consumer")
	public String insertConsumer() {
		try {
			String type = ServletActionContext.getRequest().getMethod();
			
			if(type.toUpperCase() == "GET")
			{
				return "successex";
			}
			
			getCityList();
			getCityList2();
			loadParentDealCategory();
			getDistrictList(Integer.parseInt(getCitySelected()));
			createGenderList();
			ConsumerMapper consumerMapper = new ConsumerDAO();
			// ==============================================================================================
			if (myfile != null) {
				uploadFileToMyFolder();
			} else {
				consumer.setAvatarUrl("/view/common_view/images/AccountImages/images.jpg");
			}
			// ==============================================================================================
			// INSERT CONSUMER WHEN CONSUMER'S BIRTHDAY != NULL || != ""
			if (ValidateUtil.validateEmptyString(getBirthDay()) == false) {
				// ==============================================================================================
				// PARSE STRING TO DATE
				try {
					SimpleDateFormat dateFormatter = new SimpleDateFormat("dd/MM/yyyy");
					Date date = dateFormatter.parse(getBirthDay());
					consumer.setBirthday(date);
				} catch (Exception ex) {
					showError("Lỗi trong quá trình kiểm tra ngày sinh. Vui lòng thử lại");
					return ERROR;
				}
				if (ValidateUtil.validateDateFormat(birthDay) == false) {
					showError("Ngày sinh không hợp lệ");
					return ERROR;
				}
			}
			// ==============================================================================================
			// INSERT CONSUMER WHEN CONSUMER'S BIRTHDAY == NULL || == ""
			else {
				try {
					consumer.setBirthday(null);
				} catch (Exception ex) {
					showError("Lỗi trong quá trình kiểm tra ngày sinh. Vui lòng thử lại");
					return ERROR;
				}
			}
			// ==============================================================================================
			// GET PASSWORD AND PARSE TO MD5 CODE
			password = consumer.getPassWord();
			confirmPassword = consumer.getConfirmPassword();
			try {
				if (ValidateUtil.validateEmptyString(password) == false
						&& ValidateUtil.validateEmptyString(confirmPassword) == false) {
					consumer.setPassWord(ValidateUtil.MD5Encryption(password));
					consumer.setConfirmPassword(ValidateUtil
							.MD5Encryption(confirmPassword));
				}
			}

			catch (NoSuchAlgorithmException a) {
				a.printStackTrace();
			}

			catch (UnsupportedEncodingException a) {
				a.printStackTrace();
			}

			if (validateInputField() == false) {
				return ERROR;
			}
			consumer.setCityID(Integer.parseInt(getCitySelected()));
			consumer.setDistrictID(Integer.parseInt(getDistrictSelected()));
			consumer.setGender(getGenderSelected());

			int userResult = consumerMapper.insertConsumer(consumer);
			if (userResult == 0) {
				showError("Lỗi trong quá trình tạo mới tài khoản khách hàng bình thường. Vui lòng thử lại");
				return ERROR;
			}
			// ========================================================================================
			// AUTO LOGIN AFTER REGSTER SUCCESS
			Consumer consumerResult = consumerMapper.login2(consumer);
			if (consumerResult == null) {
				showError("Lỗi trong quá trình tự đăng nhập. Vui lòng tự đăng nhập tài khoản");
				return ERROR;
			}
			consumer.setUserID(consumerResult.getUserID());
			consumer.setFullName(consumerResult.getFullName());
			setCurrentUser(consumerResult);
			loadParentDealCategory();
			getCityList2();

			// SEND EMAIL
			execute(consumer.getEmail(), 1);
			return SUCCESS;
		} catch (Exception e) {
			log.error(e.getMessage());
			showError("Lỗi trong quá trình tạo mới tài khoản khách hàng bình thường. Vui lòng thử lại");
			return ERROR;
		}
	}
	
	// Upload Image
	public String uploadFileToMyFolder() {
		try {
			ServletContext servletContext = ServletActionContext.getServletContext();
			String path = "/view/common_view/images/AccountImages";
			// getting the path to where the images will be uploaded
			String filePath = servletContext.getRealPath(path);

			File uploadDir = new File(filePath);
			// if the folder does not exits, creating it
			if (uploadDir.exists() == false) {
				uploadDir.mkdirs();
			}
			consumer.setAvatarUrl(path + "/" + consumer.getUserID() + fileExtention());
			FileUtils.copyFile(myfile, new File(uploadDir, consumer.getUserID()
					+ fileExtention()));

		} catch (Exception e) {
			System.out.println("Exception : " + e);
			addActionError(e.getMessage());
			showError("Lỗi xảy ra khi upload hình ảnh. Vui lòng thử lại");
			return ERROR;
		}
		return SUCCESS;
	}

	// Format file
	public String fileExtention() {
		try{
			if (myfileContentType.equalsIgnoreCase("image/png")) {
				return ".png";
			}
			if (myfileContentType.equalsIgnoreCase("image/jpeg")) {
				return ".jpeg";
			}
			if (myfileContentType.equalsIgnoreCase("image/jpg")) {
				return ".jpg";
			}
			return SUCCESS;
			}
			catch (Exception e){
				showError("Vui lòng chọn file ảnh theo 1 trong các định dạng sau: .png, .jpg, .jpeg");
				return ERROR;
			}
	}
	

	// ======================================================================================================
	// SHOW DISTRICT LIST WHEN CHOOSE CITY
	@Action("/master/change-city1")
	public String change_city1() {
		try {
			String type = ServletActionContext.getRequest().getMethod();
			
			if(type.toUpperCase() == "GET")
			{
				return "successex";
			}
			
			if (myfile != null) {
				uploadFileToMyFolder();
			} else {
				consumer.setAvatarUrl("/view/common_view/images/AccountImages/images.jpg");
			}
			getCityList2();
			loadParentDealCategory();
			getCityList();
			getDistrictList(Integer.parseInt(getCitySelected()));
			createGenderList();
			return ERROR;

		} catch (Exception e) {
			log.error(e.getMessage());
			return ERROR;
		}
	}

	// ======================================================================================================
	// VALIDATE INPUT FIELD
	/**
	 * Validate input input form return message, true or false
	 */
	public boolean validateInputField() {
		boolean check = true;
		// =====================================================Validate EMPTY
		if (ValidateUtil.validateEmptyString(consumer.getEmail()) == true) {
			showError("Email không được để trống");
			check = false;
		}

		if (ValidateUtil.validateEmptyString(consumer.getFullName()) == true) {
			showError("Họ tên không được để trống");
			check = false;
		}

		if (ValidateUtil.validateEmptyString(consumer.getUserID()) == true) {
			showError("Tên tài khoản không được để trống");
			check = false;
		}

		if (ValidateUtil.validateEmptyString(password) == true) {
			showError("Mật khẩu không được để trống");
			check = false;
		}

		if (ValidateUtil.validateEmptyString(confirmPassword) == true) {
			showError("Mật khẩu xác nhận không được để trống");
			check = false;
		}
		if (ValidateUtil.validateEmptyString(consumer.getAddress()) == true) {
			showError("Địa chỉ không được để trống");
			check = false;
		}
		if (ValidateUtil.validateEmptyString(consumer.getPhoneNumber()) == true) {
			showError("Số điện thoại không được để trống");
			check = false;
		}
		// =====================================================Validate LENGTH
		if (ValidateUtil.validateLengthOfPassword(password) == false) {
			showError("Chiều dài mật khẩu từ 6 đến 50 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfFullname(consumer.getFullName()) == false) {
			showError("Chiều dài Họ tên phải từ 6 đến 50 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfAddress(consumer.getAddress()) == false) {
			showError("Chiều dài địa chỉ phải từ 10 đến 100 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfPhoneNumber(consumer.getPhoneNumber()) == false) {
			showError("Chiều dài số điện thoại phải từ 10 đến 20 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfUserID(consumer.getUserID()) == false) {
			showError("Chiều dài tên đăng nhập từ 6 đến 25 kí tự");
			check = false;
		}
		// =====================================================Validate
		// STANDARD
		if (emV.validate(consumer.getEmail()) == false) {
			showError("Email không hợp lệ");
			check = false;
		}

		
		if (ValidateUtil.validateConfirmPassword(password, confirmPassword) == false) {
			showError("Mật khẩu và xác nhận mật khẩu không đúng");
			check = false;
		}

		if (ValidateUtil.validateNameStandard(consumer.getUserID()) == false) {
			showError("Tên tài khoản chỉ được chứa các kí tự a-z, A-Z, 0-9");
			check = false;
		}

		// =====================================================Validate EXIST
		if (ValidateUtil.validateConsumerExist(consumer.getUserID()) == false) {
			showError("Tên đăng nhập đã tồn tại");
			check = false;
		}

		if (ValidateUtil.validateConsumerEmailExist(consumer.getEmail()) == false) {
			showError("Email này đã tồn tại");
			check = false;
		}
		// =====================================================Validate not
		// choose city/district
		if (Integer.parseInt(getCitySelected()) == 0) {
			showError("Thành phố không được để trống.");
			check = false;
		}

		if (Integer.parseInt(getDistrictSelected()) == 0) {
			showError("Quận/huyện không được để trống.");
			check = false;
		}

		if (getGenderSelected() == "undefined") {
			showError("Giới tính không được để trống");
			check = false;
		}

		return check;
	}
	
	// ===================================================== SEND MAIL
	public void execute(String sTo, int sTypeID) throws IOException {	      
		setTo(sTo);
		setTypeID(sTypeID);
		
		MailConfigMapper mailConfigMapper = new MailConfigDAO();
		mailConfig = mailConfigMapper.selectMailConfigByID(typeID);
		
		properties.put("mail.smtp.host", mailConfig.getSmtpHost());
		String socketPort=(" "+mailConfig.getSmtpSocketPort()).trim();
		String socketClass=(" "+mailConfig.getSmtpSocketClass()).trim();
		
		if(ValidateUtil.validateEmptyString(socketPort)==false&&ValidateUtil.validateEmptyString(socketClass)==false){
			properties.put("mail.smtp.socketFactory.port", mailConfig.getSmtpSocketPort());
			properties.put("mail.smtp.socketFactory.class",	mailConfig.getSmtpSocketClass());
		}
		properties.put("mail.smtp.auth", mailConfig.getSmtpAuth());
		properties.put("mail.smtp.port", mailConfig.getSmtpPort());
		properties.put("mail.smtp.password", mailConfig.getPassword());
        
		try {
			if(ValidateUtil.validateEmptyString(socketPort)==false&&ValidateUtil.validateEmptyString(socketClass)==false){
				Session session = Session.getDefaultInstance(properties,
						new javax.mail.Authenticator() {
							protected PasswordAuthentication getPasswordAuthentication() {
								return new PasswordAuthentication(mailConfig.getFrom(), mailConfig.getPassword());
							}
						});
				
				// encording utf8 - subject
				byte[] pSubject = mailConfig.getSubject().getBytes("UTF-8");
				String subjectValue = new String(pSubject, "UTF-8");
				// encording utf8 - subject
				String iBody=mailConfig.getBody()+" Tên tài khoản: "+consumer.getUserID()+" - Mật khẩu: "+password+" ";
				byte[] pBody = iBody.getBytes("UTF-8");
				String bodyValue = new String(pBody, "UTF-8");
				
				Message message = new MimeMessage(session);
				message.setFrom(new InternetAddress(mailConfig.getFrom()));
				message.setRecipients(Message.RecipientType.TO,
						InternetAddress.parse(to));
				message.setSubject(subjectValue);
				message.setText(bodyValue);
				Transport.send(message);
				
			}else{
				// Get the default Session object.
		           Session session = Session.getDefaultInstance(properties,null);
		           
	              // Create a default MimeMessage object.
	              MimeMessage message = new MimeMessage(session);

	              // Set From: header field of the header.
	              message.setFrom(new InternetAddress(mailConfig.getFrom()));

	              // Set To: header field of the header.
	              message.addRecipient(Message.RecipientType.TO,
	                                       new InternetAddress(to));
					
	              // Set Subject: header field
	              message.setSubject(mailConfig.getSubject(), "UTF-8");

	              // get username in from
	              String[] fromItems = mailConfig.getFrom().split("@");
	              String username=fromItems[0];
	              
	              // Now set the actual message
	              message.setText(mailConfig.getBody()+" Tên tài khoản: "+consumer.getUserID()+" - Mật khẩu: "+password+" ", "UTF-8");
				Transport transport = session.getTransport("smtp");
				transport.connect(mailConfig.getSmtpHost(),username, mailConfig.getPassword());
				transport.sendMessage(message, message.getAllRecipients());
				transport.close();
			}

		} catch (Exception e) {
			setErrTimes(errTimes + 1);
			if(errTimes>1){
				log.error("Send mail register consumer fail for "+consumer.getUserID()+" with email address: "+to+ " times 2.");
				setErrTimes(0);
			}
			else{
				log.error("Send mail register consumer fail for "+consumer.getUserID()+" with email address: "+to+ " times 1.");
				execute(consumer.getEmail(), 1);
			}
		}
	}

	// ======================================================================================================
	// GET MODEL FOR CONSUMER
	@Override
	public Consumer getModel() {
		// TODO Auto-generated method stub
		return consumer;
	}

}
